/**
 * slice.io
 * Copyright(C) 2018 liumurong
 */

import * as Application from 'koa';
import * as Router from 'koa-router';
import { sliceRouter } from './router';
import { SliceOptions } from './receive/models';
import { ReceiverHelper } from './receive/receiverhelper';
import { Receiver } from './receive/receiver';
import { Readable } from 'stream';

/**
 * 基于Koa2的断点续传插件
 * 定义断点续传
 * @param opts 选项
 */
export function sliceResume(app: Application, opts: SliceOptions = {}) {
    // 路由
    app.use(sliceRouter.routes());
    // 配置
    ReceiverHelper.instance.setOptions(opts);
    // 启动垃圾清理机制
    //ReceiverHelper.instance.startScheduleTask();
}
/**
 * 基于Koa2的断点续传插件
 * 解析通过断点续传的方式上传的文件
 * @param ctx 上下文
 * @param next 
 */
export async function sliceArchiver(ctx: Application.Context, next: () => Promise<any>) {
    ctx.slice = { stream: null, metadata: null };
    //json/rest/query 三种方式传递此参数
    let hashCode = (ctx.request.body && ctx.request.body[ReceiverHelper.instance.hashFieldName]) || (ctx.params && ctx.params[ReceiverHelper.instance.hashFieldName]) || (ctx.query && ctx.query[ReceiverHelper.instance.hashFieldName]);
    if (!hashCode) {
        ctx.body = {
            stat: 1,
            msg: "未包含文件Hash值"
        }
        return;
    }
    let rootHashCode = await ReceiverHelper.instance.receiver.getNodeHash(hashCode, "0", "0");
    if (rootHashCode !== hashCode) {
        ctx.body = {
            stat: 1,
            msg: "文件Hash值无效，可能并不存在此文件"
        }
        return;
    }
    const fileStat = await ReceiverHelper.instance.receiver.getMetadata(hashCode);
    ctx.slice.metadata = fileStat;
    ctx.slice.stream = ReceiverHelper.instance.receiver.getStream(hashCode);
    await next();
}

/**
 * 通过文件获取Hash流
 * @param hashCode 文件根hash值
 */
export async function sliceArchiverStream(hashCode: string): Promise<Readable> {
    let fileMeta = await ReceiverHelper.instance.receiver.getMetadata(hashCode);
    if (!fileMeta || fileMeta.hash !== fileMeta.root) {
        return Promise.reject("未存在合法的文件");
    }
    return ReceiverHelper.instance.receiver.getStream(hashCode);
}
/**
 * 设置slice选项
 * @param opts slice选项
 */
export function setSliceOptions(opts: SliceOptions = {}) {
    ReceiverHelper.instance.setOptions(opts);
}
